package org.brisling.sysman.service;



import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import javax.persistence.Query;
import javax.persistence.TypedQuery;

import org.brisling.authorize.shiro.ShiroSecurityService;
import org.brisling.base.domain.RetDomain;
import org.brisling.common.ConstSysParam;
import org.brisling.common.exception.BizCodeMustNotNullException;
import org.brisling.common.exception.SessionExpiredException;
import org.brisling.common.util.JsonUtil;
import org.brisling.sysman.domain.Permissions;
import org.brisling.sysman.domain.Users;
import org.brisling.sysman.repository.PermissionsRepo;
import org.brisling.sysman.service.base.BaseSysmanTreeService;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;


@RestController
@RequestMapping("/permission")
/**
 * 用戶后台服務service
 * @Author : jackson wang
 * @Date   : 2015年6月8日 下午4:18:01
 * @Update : 2015-9-26
 * @version: 1.0
 */
public class PermissionService extends BaseSysmanTreeService<Permissions>{
		
	private static Logger log = Logger.getLogger(PermissionService.class);
	
	final String PERMISSION_HQL = " FROM Permissions p, " +
			"RolesPermission rp,  UserRoles ur,  Users u "+
			"WHERE p.id = rp.permissionid AND rp.roleid = ur.roleid AND ur.userid = u.id AND p.isused='Y' AND p.status='A' ";
	
	final String SUPER_PERMISSION_HQL = " FROM Permissions p "+
			"WHERE p.isused='Y' AND p.status='A' ";
	
	final String NORMAL_PERMISSION_HQL = "SELECT p " + PERMISSION_HQL;
	
	final String NORMAL_MENU_HQL = "SELECT DISTINCT p " + PERMISSION_HQL;
	
	final String ADMIN_MENU_HQL = "SELECT DISTINCT p " + SUPER_PERMISSION_HQL;
	
	final String ADMIN_PERMISSION_HQL = "SELECT p " + SUPER_PERMISSION_HQL;
	
	
	final String PERMISSION_SQL = " FROM Permissions p " +
			"LEFT JOIN RolesPermission rp ON p.id = rp.permissionid "+
			"LEFT JOIN UserRoles ur ON rp.roleid = ur.roleid "+
			"LEFT JOIN Users u ON ur.userid = u.id "+
			"WHERE p.isused='Y' AND p.status='A' ";
	final String NORMAL_PERMISSION_SQL = "SELECT p.* FROM SYSMAN_PERMISSIONS p " +
			"LEFT JOIN SYSMAN_ROLESPERMISSION rp ON p.id = rp.permissionid "+
			"LEFT JOIN SYSMAN_USERROLE ur ON rp.roleid = ur.roleid "+
			"LEFT JOIN SYSMAN_USERS u ON ur.userid = u.id "+
			"WHERE p.isused='Y' AND p.status='A' ";
	
	final String NORMAL_MENU_SQL = "SELECT DISTINCT p.* " + PERMISSION_SQL;
	
	final String NORMAL_ORDER_SQL = " ORDER BY p.sortedid";
	
	final String NORMAL_MENU_PERMISSION_SQL =  NORMAL_MENU_SQL+ "AND p.type='F' " ;
	
	final String NORMAL_MENU_PERMISSION_HQL =  NORMAL_MENU_HQL+ "AND p.type='F' " ;
	
	final String NORMAL_OPERATE_PERMISSION_SQL=NORMAL_PERMISSION_SQL +"AND p.type='O' ";
	
	final String NORMAL_USER_PARAM_SQL = "AND u.id = :userid ";
	
	
		
	@Autowired
	private PermissionsRepo baseRepo;
	
	@Autowired
	private ShiroSecurityService shiroSecurityService;
	
	
	
	public PermissionService(){
		this.moduleName = ConstSysParam.MODULE_PERMISSION;
	}
	/**
	 * 获取业务主页面 
	 * @return
	 */
	@RequestMapping("/mainPage.action")
	public ModelAndView getMainPage(){
		log.debug("permission main page loaded ...");
		return this.getBizMainPage();
	}
	
	/**
	 * 获取业务编辑页面
	 * @return
	 */
	@RequestMapping("/editPage.action")
	public ModelAndView getEditPage(){
		return this.getBizEditPage();
	}
	
	
	/**
	 * 获取组织架构树
	 * @param id
	 * @return
	 */
	@RequestMapping("/getTree.action")
	public List<Permissions> getTreeNode(@RequestParam(value="id",required=false) Long id){
		return (List<Permissions>) super.getNode(id);
	}
	
	/**
	 * 删除记录,单条或批量删除记录,id不为空，执行单条删除，id为空且ids不为空，执行批量删除
	 * @param id	待删除的单条记录id
	 * @param ids	待删除的多条记录id，以','分隔
	 * @return
	 */
	@RequestMapping("/del.action")
	public RetDomain delRow(@RequestParam(value="id",required=false) Long id,@RequestParam(value="ids",required=false) String ids){
				
		return super.delRows(id, ids);		 
	}
	
	/**
	 * 删除记录,单条或批量删除记录,id不为空，执行单条删除，id为空且ids不为空，执行批量删除
	 * @param id	待删除的单条记录id
	 * @param ids	待删除的多条记录id，以','分隔
	 * @return
	 */
	@RequestMapping("/flowDel.action")
	public RetDomain delFlowRow(@RequestParam(value="id",required=false) Long id,@RequestParam(value="ids",required=false) String ids){
		
			return delRow(id,ids);
		
	}
	
	/**
	 * 保存权限资源对象
	 * @param body
	 */
	@RequestMapping("/save.action")
	public Permissions save(@RequestBody String body){
		Permissions dept = JsonUtil.bodyToObj(body, Permissions.class);
		super.save(dept);
		return dept;
	}
	
	/**
	 * 批量保存权限资源对象
	 * @param List
	 */
	@RequestMapping("/saveList.action")
	public RetDomain saveList(List<Permissions> permissions){		
		return super.saveList(permissions);
		
	}
	
	/**
	 * 
	 * @return 用户具备访问权限的业务模块清单
	 * @throws Exception 
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping("/getUserMenu.action")
	@ResponseBody
	public List<Permissions> getUserMenu() throws SessionExpiredException{
		
		
		
		Users user = shiroSecurityService.getCurrentUser();
		
		if(user.getId()==null)
			throw new SessionExpiredException();
		
		String sql = "";
		
		
		TypedQuery query =null;
		if ("admin".equals(user.getName()))
		{
			sql = ADMIN_MENU_HQL + NORMAL_ORDER_SQL;
			query =entityManager.createQuery(sql,Permissions.class);
		}else{
			sql= NORMAL_MENU_PERMISSION_HQL +NORMAL_USER_PARAM_SQL + NORMAL_ORDER_SQL;
			query = entityManager.createQuery(sql,Permissions.class)
						.setParameter("userid", user.getId());						
						
		}
		
		log.debug(sql);
		
		List<Permissions> permissionsList = query.getResultList();
		
		//循环迭代生成linkedhashmap		
		List<Permissions> parentList=new ArrayList<Permissions>();
		for (Permissions obj : permissionsList)
		{			
			if (obj.getParentid()==null)
			{
				
				List<Permissions> childList=new ArrayList<Permissions>();
				for (Permissions obj2 : permissionsList){
					
					if ( (obj2.getParentid()!=null) && (obj2.getParentid().equals(obj.getId()))){						
						childList.add(obj2);
					}
				}
				obj.setChild(childList);
				parentList.add(obj);
			}
		}
		return parentList;
	}
	
	/**
	 * 
	 * @return 用户具备访问权限的业务模块清单
	 * @throws SessionExpiredException 
	 * @throws Exception 
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping("/getUserBizOperate.action")
	@ResponseBody
	public List<LinkedHashMap> getUserBizOperate(@RequestParam(value="id",required=false)Long userid,
			@RequestParam(value="bizcode",required=false)String bizcode,@RequestBody String body) throws BizCodeMustNotNullException, SessionExpiredException{	
		
//		if(userid==null)
//			throw new SessionExpiredException();
		
		Users user = shiroSecurityService.getCurrentUser();
		
//		if(userid!=user.getId())
//			throw new SessionExpiredException();
		
		if((bizcode==null)||(bizcode.trim().length()<=0))
			throw new BizCodeMustNotNullException();
		
		String sql = this.NORMAL_OPERATE_PERMISSION_SQL + " AND p.fullBizcode like :fullBizcode";
		String codeParam = "%" + bizcode +"%";
		
		
		Query query =null;

		if ("admin".equals(user.getName()))
		{
			sql += NORMAL_ORDER_SQL;
			query =entityManager.createNativeQuery(sql)
					.setParameter("fullBizcode", codeParam);
		}else{
			sql+=this.NORMAL_USER_PARAM_SQL + NORMAL_ORDER_SQL;
			query = entityManager.createQuery(sql,Permissions.class)
						.setParameter("fullBizcode", codeParam)
						.setParameter("userid", user.getId());						
						
		}
		
		log.debug(sql);
		query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List<LinkedHashMap> permissionsList = query.getResultList();
		
		return permissionsList;
	}
	
	public Permissions getByFullBizcode(String fullbizcode){
		return baseRepo.findByFullBizcode(fullbizcode);
	}
	
	/**
	 * 根据业务代码获取完整业务代码
	 * @param bizcode
	 * @return
	 */
	public Permissions getByBizcode(String bizcode){
		List<Permissions> lists = baseRepo.findByBizcode(bizcode);
		if(lists!=null && lists.size()==1 ){
			
			return lists.get(0);
		}
		return null;
	}
	
	/**
	 * 自动生成业务模块权限
	 * @param id		权限所属业务资源节点
	 * @param typeId	权限类型定义，1：非流程业务；2：文档业务；3：流程业务
	 * @return
	 */
	@RequestMapping("/generatePermissions.action")
	public RetDomain autoGeneratePermissions(@RequestParam(value="id",required=false) Long id,@RequestParam(value="type",required=false) Long typeId){
		
		RetDomain domain = new RetDomain();
		//权限类型定义，1：非流程业务；2：文档业务；3：流程业务
		Long _tid = typeId ==null ?1:typeId;
		if(id!=null){
			Permissions _dept =this.getOne(id);
			
			//根据类型获取待增加权限配置
			List<Permissions> add_permission =getPermissionConfig(_dept,_tid);
			
			//查询已有权限配置
			List<Permissions> exist_permission = this.getTreeNode(id);
			
			List<Permissions> delList = new ArrayList<Permissions>();
			
			//循环遍历剔除已有权限，避免重复
			if(exist_permission!=null && exist_permission.size()>0){
				if(add_permission!=null && add_permission.size()>0){
//					int exist_count = exist_permission.size();
//					int add_count = add_permission.size();
					
					//循环遍历待添加权限
					for(Permissions ap:add_permission){						
						
						//循环遍历已存在权限
						for(Permissions ep:exist_permission){	
						
							
							//判断已存在权限与待添加权限不为空
							if(ap!=null && ep!=null){
								
								//判断已存在权限与待添加权限名称是否相同
								if(ap.getName().compareTo(ep.getName())==0){
									//清除已存在权限，避免权限定义重复
									delList.add(ap);
//									add_permission.remove(ap);
								}
							}
						}
					}
				}
			}
			
			if(delList!=null &&delList.size()>0){
				for(Permissions _p:delList){
					add_permission.remove(_p);
				}
			}
			if(add_permission!=null && add_permission.size()>0){
				add_permission = addFullBizCode(add_permission);
				return this.saveList(add_permission);
			}
		}
		return domain;
	}
	
	/**
	 * 获取指定节点的权限资源名称
	 * @param d		权限所属业务资源节点
	 * @param type	权限类型,1：非流程业务；2：文档业务；3：流程业务
	 * @return
	 */
	private List<Permissions> getPermissionConfig(Permissions d,Long type){
		
		
		
		String permissionStr = null;
		if(d!=null && d.getId()!=null){
			String _s = "{\"name\":\"新增\",\"bizcode\":\"listAddReplace\",\"sortedid\":\"10\",\"icon-cls\":\"icon-add\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"listUsed\": \"on\"},"+
					"{\"name\":\"编辑\",\"bizcode\":\"listEditReplace\",\"sortedid\":\"20\",\"icon-cls\":\"icon-edit\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"listUsed\": \"on\"},"+
					"{\"name\":\"删除\",\"bizcode\":\"listDel\",\"sortedid\":\"30\",\"icon-cls\":\"icon-remove\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"listUsed\": \"on\"},"+
					"{\"name\":\"保存\",\"bizcode\":\"editSaveReplace\",\"sortedid\":\"70\",\"icon-cls\":\"icon-save\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"editUsed\":\"on\"},"+
					"{\"name\":\"附件\",\"bizcode\":\"editArchive\",\"sortedid\":\"80\",\"icon-cls\":\"icon-archive\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"editUsed\":\"on\"},"+
					"{\"name\":\"取消\",\"bizcode\":\"editCancelReplace\",\"sortedid\":\"200\",\"icon-cls\":\"icon-cancel\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"editUsed\":\"on\"}";
			
			Long _type = type==null?1l:type;
			switch(_type.intValue()){
			case 2:
				//文档类业务流程
				String docPermissionStr = _s +
					","+
					"{\"name\":\"批量提交\",\"bizcode\":\"listSubmit\",\"sortedid\":\"40\",\"icon-cls\":\"icon-lock\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"listUsed\": \"on\"},"+
					"{\"name\":\"批量退回\",\"bizcode\":\"listDenide\",\"sortedid\":\"50\",\"icon-cls\":\"icon-denide\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"listUsed\": \"on\"},"+
					"{\"name\":\"批量审核\",\"bizcode\":\"listPermit\",\"sortedid\":\"60\",\"icon-cls\":\"icon-ok\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"listUsed\": \"on\"},"+
					"{\"name\":\"提交\",\"bizcode\":\"editSubmit\",\"sortedid\":\"100\",\"icon-cls:\"icon-lock\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"editUsed\":\"on\"},"+
					"{\"name\":\"审核未通过\",\"bizcode\":\"editDenide\",\"sortedid\":\"110\",\"icon-cls\":\"icon-denide\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"editUsed\":\"on\"},"+
					"{\"name\":\"审核通过\",\"bizcode\":\"editPermit\",\"sortedid\":\"120\",\"icon-cls:\"icon-ok\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"editUsed\":\"on\"}";
				
				permissionStr = String.format(docPermissionStr, d.getId());
				break;
			case 3:
				//审批流程类业务
				//文档类业务流程
				String flowPermissionStr = _s +
					","+					
					"{\"name\":\"回退\",\"bizcode\":\"editUndoReplace\",\"sortedid\":\"90\",\"icon-cls\":\"icon-undo\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"editUsed\":\"on\"},"+
					"{\"name\":\"发送\",\"bizcode\":\"editRedoReplace\",\"sortedid\":\"100\",\"icon-cls\":\"icon-redo\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"%1$s\",\"editUsed\":\"on\"}";
					
				
				permissionStr = String.format(flowPermissionStr, d.getId());
				break;
			default:
				permissionStr = String.format(_s, d.getId());
			}
		}
		//permissionStr = "{\"name\":\"批量提交\",\"bizcode\":\"listSubmit\",\"sortedid\":\"40\",\"icon-cls\":\"icon-lock\",\"isused\":\"Y\",\"status\":\"A\",\"type\":\"O\",\"parentid\":\"8163\"}";
		permissionStr = "[" + permissionStr + "]";
		ObjectMapper mapper = new ObjectMapper();
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);	
		JavaType _javaType = mapper.getTypeFactory().constructCollectionType(List.class, Permissions.class);
		List<Permissions> lists = null;
		try {
			lists =  mapper.readValue(permissionStr, _javaType);
			
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}		
		
		
		return lists;
	}
	
	private List<Permissions> addFullBizCode(List<Permissions> lists){
		for(Permissions t: lists){
			String parentBizcode = "";
			String childFullBizcode = "";
			Long _parentid =t.getParentid();
			if((_parentid!=null)&&(_parentid.toString().trim().length()>0)){
				//传人entity parentid不为空			
				Permissions parent = this.getOne(_parentid);				
				if(parent!=null){
					//获取上级完整业务编码
					parentBizcode = parent.getFullBizcode();
					if((parentBizcode!=null)&&(parentBizcode.trim().length()>0)){
						childFullBizcode =parentBizcode;
					}
				}							
			}
			
			//获取本级业务编码
			String childBizcode = t.getBizcode();
			if((childBizcode!=null)&&(childBizcode.trim().length()>0)){
				childFullBizcode =childFullBizcode==""?childBizcode:childFullBizcode +":" + childBizcode;
			}
			//本级完整业务编码 = 上级完整业务编码  + 本级业务编码
			t.setFullBizcode(childFullBizcode);	
		}
		return lists;
	}
}
